package com.cauli.file.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cauli.file.component.FileComponent;
import com.cauli.file.component.FileDealComp;
import com.cauli.file.model.dto.share.CheckEndTimeDTO;
import com.cauli.file.model.dto.share.CheckExtractionCodeDTO;
import com.cauli.file.model.dto.share.SaveShareFileDTO;
import com.cauli.file.model.dto.share.ShareFileDTO;
import com.cauli.file.model.dto.share.ShareFileListDTO;
import com.cauli.file.model.dto.share.ShareListDTO;
import com.cauli.file.model.dto.share.ShareTypeDTO;
import com.cauli.file.model.entity.Share;
import com.cauli.file.model.entity.ShareFile;
import com.cauli.file.model.entity.UserFile;
import com.cauli.file.model.vo.share.ShareFileListVO;
import com.cauli.file.model.vo.share.ShareFileVO;
import com.cauli.file.model.vo.share.ShareListVO;
import com.cauli.file.model.vo.share.ShareTypeVO;
import com.cauli.file.service.ShareFileService;
import com.cauli.file.service.ShareService;
import com.cauli.file.service.UserFileService;
import com.cauli.utils.util.ResultResponse;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.qiwenshare.common.anno.MyLog;
import com.qiwenshare.common.util.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author Cauli
 * @date 2023-03-18 12:00
 * @description 文件分享 前端控制器
 */
@Api(tags = "文件分享")
@ApiSort(4)
@RestController
@RequestMapping("/share")
@Slf4j
public class ShareController {
    @Autowired
    private ShareFileService shareFileService;

    @Autowired
    private ShareService shareService;

    @Autowired
    private UserFileService userFileService;

    @Autowired
    private FileDealComp fileDealComp;

    public static final String CURRENT_MODULE = "文件分享";

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "查看已分享列表")
    @GetMapping(value = "/shareList")
    public ResultResponse<ShareListVO> shareList(ShareListDTO shareListDTO) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<ShareListVO> shareList = shareService.selectShareList(shareListDTO, userId);

        Long total = shareService.selectShareListTotalCount(shareListDTO, userId);

        return ResultResponse.success().dataList(shareList, total);
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分享文件列表")
    @GetMapping(value = "/shareFileList")
    public ResultResponse<ShareFileListVO> shareFileList(ShareFileListDTO shareFileListBySecretDTO) {
        String shareBatchNum = shareFileListBySecretDTO.getShareBatchNum();
        String shareFilePath = shareFileListBySecretDTO.getShareFilePath();
        List<ShareFileListVO> list = shareFileService.selectShareFileList(shareBatchNum, shareFilePath);
        for (ShareFileListVO shareFileListVO : list) {
            shareFileListVO.setShareFilePath(shareFilePath);
        }
        return ResultResponse.success().dataList(list, Long.valueOf(list.size()));
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分享类型")
    @GetMapping(value = "/shareType")
    public ResultResponse<ShareTypeVO> shareType(ShareTypeDTO shareTypeDTO) {
        // 可用此接口判断是否需要提取码
        LambdaQueryWrapper<Share> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Share::getShareBatchNum, shareTypeDTO.getShareBatchNum());
        Share share = shareService.getOne(lambdaQueryWrapper);
        ShareTypeVO shareTypeVO = new ShareTypeVO();
        shareTypeVO.setShareType(share.getShareType());
        return ResultResponse.success().data(shareTypeVO);
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "校验提取码")
    @PostMapping(value = "/checkExtractionCode")
    public ResultResponse<String> checkExtractionCode(CheckExtractionCodeDTO checkExtractionCodeDTO) {
        LambdaQueryWrapper<Share> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Share::getShareBatchNum, checkExtractionCodeDTO.getShareBatchNum())
                .eq(Share::getExtractionCode, checkExtractionCodeDTO.getExtractionCode());
        List<Share> list = shareService.list(lambdaQueryWrapper);
        if (list.isEmpty()) {
            return ResultResponse.fail().message("提取码错误");
        } else {
            return ResultResponse.success();
        }
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "校验过期时间")
    @PostMapping(value = "/checkEndTime")
    public ResultResponse<String> checkEndTime(CheckEndTimeDTO checkEndTimeDTO) {
        LambdaQueryWrapper<Share> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Share::getShareBatchNum, checkEndTimeDTO.getShareBatchNum());
        Share share = shareService.getOne(lambdaQueryWrapper);
        if (share == null) {
            return ResultResponse.fail().message("文件不存在！");
        }
//        String endTime = share.getEndTime();
//        Date endTimeDate = null;
//        try {
//            endTimeDate = DateUtil.getDateByFormatString(endTime, "yyyy-MM-dd HH:mm:ss");
//        } catch (ParseException e) {
//            log.error("日期解析失败：{}", e);
//        }
//        if (new Date().after(endTimeDate)) {
        if (share.getShareType() == 1) {
            return ResultResponse.fail().message("分享已过期");
        } else {
            return ResultResponse.success();
        }
    }

    @MyLog(operation = "分享文件", module = CURRENT_MODULE)
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "分享文件")
    @PostMapping(value = "/shareFile")
    public ResultResponse<ShareFileVO> shareFile(@RequestBody ShareFileDTO shareFileDTO) {
        long userId = StpUtil.getLoginIdAsLong();
        ShareFileVO shareFileVO = new ShareFileVO();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        Share share = new Share();
        BeanUtil.copyProperties(shareFileDTO, share);
        share.setShareTime(DateUtil.getCurrentTime());
        share.setUserId(userId);
        share.setShareStatus(0);
        if (shareFileDTO.getShareType() == 1) {
            String extractionCode = RandomUtil.randomNumbers(6);
            share.setExtractionCode(extractionCode);
            shareFileVO.setExtractionCode(share.getExtractionCode());
        }
        share.setShareBatchNum(uuid);
        shareService.save(share);

        List<ShareFile> fileList = JSON.parseArray(shareFileDTO.getFiles(), ShareFile.class);
        List<ShareFile> saveFileList = new ArrayList<>();
        for (ShareFile shareFile : fileList) {
            UserFile userFile = userFileService.getById(shareFile.getUserFileId());
            if (userFile.getUserId().compareTo(StpUtil.getLoginIdAsLong()) != 0) {
                return ResultResponse.fail().message("您只能分享自己的文件");
            }
            if (userFile.getIsDir() == 1) {
                FileComponent fileComponent = new FileComponent(userFile.getFilePath(), userFile.getFileName(), true);
                List<UserFile> userFileList = userFileService.selectUserFileByLikeRightFilePath(fileComponent.getPath(), userId);
                for (UserFile u : userFileList) {
                    ShareFile shareFile1 = new ShareFile();
                    shareFile1.setShareFileId(Long.valueOf(IdUtil.getSnowflakeNextIdStr()));
                    shareFile1.setUserFileId(u.getUserFileId());
                    shareFile1.setShareBatchNum(uuid);
                    shareFile1.setShareFilePath(u.getFilePath().replaceFirst(userFile.getFilePath().equals("/") ? "" : userFile.getFilePath(), ""));
                    saveFileList.add(shareFile1);
                }
            }
            shareFile.setShareFilePath("/");
            shareFile.setShareBatchNum(uuid);
            saveFileList.add(shareFile);
        }
        shareFileService.batchInsertShareFile(saveFileList);
        shareFileVO.setShareBatchNum(uuid);


        // ------------------文件延迟处理------------------
        fileDealComp.expiredShareFile(uuid);

        return ResultResponse.success().data(shareFileVO);
    }

    @MyLog(operation = "保存分享文件", module = CURRENT_MODULE)
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "保存分享文件")
    @PostMapping(value = "/saveShareFile")
    public ResultResponse saveShareFile(@RequestBody SaveShareFileDTO saveShareFileDTO) {
        long userId = StpUtil.getLoginIdAsLong();

        List<ShareFile> fileList = JSON.parseArray(saveShareFileDTO.getFiles(), ShareFile.class);
        String saveFilePath = saveShareFileDTO.getFilePath();

        List<UserFile> saveUserFileList = new ArrayList<>();
        for (ShareFile shareFile : fileList) {
            UserFile userFile = userFileService.getById(shareFile.getUserFileId());
            String fileName = userFile.getFileName();
            String saveFileName = fileDealComp.getRepeatFileName(userFile, saveFilePath);

            if (userFile.getIsDir() == 1) {
                List<UserFile> userFileList = userFileService.selectUserFileByLikeRightFilePath(new FileComponent(userFile.getFilePath(), userFile.getFileName(), true).getPath(), userFile.getUserId());
                log.info("查询文件列表：" + JSON.toJSONString(userFileList));
                String filePath = userFile.getFilePath();
                userFileList.forEach(p -> {
                    p.setUserId(userId);
                    p.setFilePath(p.getFilePath().replaceFirst(filePath + "/" + fileName, saveFilePath + "/" + saveFileName));
                    saveUserFileList.add(p);
                    log.info("当前文件：" + JSON.toJSONString(p));

                });
            }
            userFile.setUserFileId(null);
            userFile.setUserId(userId);
            userFile.setFilePath(saveFilePath);
            userFile.setFileName(saveFileName);
            saveUserFileList.add(userFile);
        }
        log.info("----------" + JSON.toJSONString(saveUserFileList));
        userFileService.saveBatch(saveUserFileList);

        return ResultResponse.success();
    }
}
